package cn.wizzer.app.web.modules.controllers.platform.user;

import cn.wizzer.app.match.modules.models.constant.Fields;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.vo.UserAccountVo;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.web.commons.ulog.annotation.SLog;
import cn.wizzer.app.web.commons.utils.StringUtil;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.page.Pagination;
import cn.wizzer.util.CommonUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import redis.clients.jedis.ScanParams;

import java.util.List;

import static cn.wizzer.app.user.modules.models.constant.ChatConstant.SESSION_ENABLE_USERS;


@IocBean
@At("/platform/user/manager")
public class UserController {
    private static final Log log = Logs.get();

    @Inject
    @Reference
    private UserService userService;

    @Inject
    private RedisService redisService;

    @At("/")
    @Ok("beetl:/platform/user/manager/index.html")
    @RequiresPermissions("user.manager.list")
    public void index() {

    }

    /**
     * 查询用户（分页）
     *
     * @param conditionData 条件集：是否主播、是否禁言等
     * @param searchKeyword String(要搜索的内容)
     * @param searchDate    String[](按日期时间搜索)
     * @param pageNumber    int
     * @param pageSize      int
     * @return Object
     */
    @At
    @Ok("json:full")
    @RequiresPermissions("user.manager.list")
    public Object data(@Param("conditionData") String conditionData,
                       @Param("searchKeyword") String searchKeyword,
                       @Param("searchDate") String[] searchDate,
                       @Param("pageNumber") int pageNumber,
                       @Param("pageSize") int pageSize) {
        Pagination pagination = userService.userListNew(conditionData, searchKeyword, searchDate, pageNumber, pageSize);
        int onlineNum = userService.count(Cnd.where("is_online", "=", 1));
        return Result.success().addData(Result.createMap("pagination", pagination, "onlineNum", onlineNum));
    }

    /**
     * 添加用户
     *
     * @param user       User
     * @param inviteCode
     * @return Object
     */
    @At("/add")
    @Ok("json")
    @RequiresPermissions("user.manager.add")
    @SLog(tag = "新建User", msg = "昵称:${args[0].nickName}")
    public Object add(@Param("..") User user, String inviteCode) {
        //验证手机号码格式
        CommonUtil.isPhone(user.getPhone());
        user.setOpBy(StringUtil.getPlatformUid());
        //currentTimestamp
        user.setOpAt(1L);
        userService.insertUser(user, inviteCode);
        return Result.success();
    }


    /**
     * 查询用户
     *
     * @param id String
     * @return Object
     */
    @At("/edit/?")
    @Ok("json:full")
    public Object edit(String id) {
        try {
            return Result.success(userService.fetch(id));
        } catch (Exception e) {
            return Result.error();
        }
    }

    /**
     * 修改用户
     *
     * @param user User
     * @return Object
     */
    @At("/editDo")
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "修改用户", msg = "昵称:${args[1].getAttribute('nickName')}")
    public Object editDo(@Param("..") User user) {
        if (Strings.isBlank(user.getPhone())) {
            return Result.error("手机号码不能为空");
        }
        //禁用后离线用户
        if (user.isDisabled()) {
            //扫描当前在线的用户
            ScanParams scanParams = new ScanParams();
            scanParams.match("user:token:*");
            scanParams.count(Integer.MAX_VALUE);
            List<String> keys = redisService.scan("0", scanParams).getResult();
            //匹配该用户登录缓存
            Object[] loginKey = keys.stream().filter(key -> key.contains(user.getId())).toArray();
            //同步将用户强行下线
            for (Object o : loginKey) {
                String key = o.toString();
                redisService.del(key);
            }
            //计算用户登录时长
            user.setLoginDuration(userService.calculateLoginDuration(user.getId()));
            //用户在线状态设置为离线
            user.setOnline(false);
        }
        userService.updateUser(user);
        return Result.success();
    }

    /**
     * 启用用户
     *
     * @param id String
     * @return Object
     */
    @At("/enable/?")
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "启用用户", msg = "昵称:${args[1].getAttribute('nickName')}")
    public Object enable(String id) {
        userService.update(Chain.make("disabled", false), Cnd.where("id", "=", id));
        return Result.success();
    }

    /**
     * 是否主播
     *
     * @param id String
     * @return Object
     */
    @At("/anchor")
    @Ok("json")
    @RequiresPermissions("user.manager.chat.anchor")
    @SLog(tag = "是否主播")
    public Object anchorDisable(@Param("id") String id, @Param("disable") boolean disable) {
        userService.update(Chain.make("anchor", disable), Cnd.where("id", "=", id));
        return Result.success();
    }

    /**
     * 禁言
     *
     * @param id String
     * @return Object
     */
    @At("/session")
    @Ok("json")
    @RequiresPermissions("user.manager.chat.session")
    @SLog(tag = "是否禁言")
    public Object sessionDisable(@Param("id") String id, @Param("disable") boolean disable) {
        userService.update(Chain.make("session_disabled", disable), Cnd.where("id", "=", id));
        //同步禁言到用户端
        redisService.hset(SESSION_ENABLE_USERS, id, !disable ? Fields.TRUE_STR : Fields.FALSE_STR);
        return Result.success();
    }

    /**
     * 默认房管
     *
     * @param id String
     * @return Object
     */
    @At("/manage")
    @Ok("json")
    @RequiresPermissions("user.manager.chat.manage")
    @SLog(tag = "默认房管")
    public Object manage(@Param("id") String id, @Param("flag") boolean flag) {
        userService.update(Chain.make("room_manager", flag), Cnd.where("id", "=", id));
        return Result.success();
    }

    /**
     * 禁用用户
     *
     * @param id String
     * @return Object
     */
    @At("/disable/?")
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "禁用用户", msg = "昵称:${args[1].getAttribute('nickName')}")
    public Object disable(String id) {
        userService.update(Chain.make("disabled", true), Cnd.where("id", "=", id));
        return Result.success();
    }


    /**
     * 用户收款权限
     *
     * @param id        用户id
     * @param isCollect boolean 收款开关
     * @return
     */
    @At("/isCollect")
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "收款权限")
    public Object isCollect(@Param("id") String id, @Param("isCollect") boolean isCollect) {
        userService.update(Chain.make("is_collect", isCollect), Cnd.where("id", "=", id));
        return Result.success();
    }

    /**
     * 游戏开关
     *
     * @param id       用户id
     * @param playable boolean 收款开关
     * @return
     */
    @At("/setPlayable")
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "收款权限")
    public Object setPlayable(@Param("id") String id, @Param("playable") boolean playable) {
        userService.update(Chain.make("playable", playable), Cnd.where("id", "=", id));
        return Result.success();
    }

    /**
     * 代理开关
     *
     * @param id    用户id
     * @param agent boolean 收款开关
     * @return
     */
    @At("/setAgent")
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "收款权限")
    public Object setAgent(@Param("id") String id, @Param("agent") boolean agent) {
        userService.update(Chain.make("agent", agent), Cnd.where("id", "=", id));
        return Result.success();
    }

    /**
     * 观点发布开关
     *
     * @param id        用户id
     * @param certified boolean 开关
     * @return
     */
    @At()
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "允许发布观点")
    public Object setCertified(@Param("id") String id, @Param("certified") boolean certified) {
        userService.update(Chain.make("certified", certified), Cnd.where("id", "=", id));
        return Result.success();
    }

    @At()
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "用户状态")
    public Object setDisabled(@Param("id") String id, @Param("disabled") boolean disabled) {
        if (disabled) {
            //扫描当前在线的用户
            ScanParams scanParams = new ScanParams();
            scanParams.match("user:token:*");
            scanParams.count(Integer.MAX_VALUE);
            List<String> keys = redisService.scan("0", scanParams).getResult();
            //匹配该用户登录缓存
            Object[] loginKey = keys.stream().filter(key -> key.contains(id)).toArray();
            //同步将用户强行下线
            for (Object o : loginKey) {
                redisService.del(o.toString());
            }
            userService.update(Chain.make("disabled", true).add("is_online", 0), Cnd.where("id", "=", id));
        } else {
            userService.update(Chain.make("disabled", false), Cnd.where("id", "=", id));
        }
        return Result.success();
    }

    @At()
    @Ok("json")
    @RequiresPermissions("user.manager.edit")
    @SLog(tag = "设置客服")
    public Object setAttendant(@Param("id") String id, @Param("attendant") boolean attendant) {
        userService.update(Chain.make("attendant", attendant), Cnd.where("id", "=", id));
        return Result.success();
    }

    @At("/searchAccount")
    @Ok("json:full")
    public Object searchAccount(String key, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize) {
        Sql sql = Sqls.create("SELECT a.*,u.`nickName`,u.`phone` FROM user_account a ");
        Sql countSql = Sqls.create("SELECT COUNT(1) FROM user_account a ");
        Sql joinSql = Sqls.create("LEFT JOIN USER u ON u.id = a.user_id " +
                "$condition ");
        Cnd cnd = Cnd.NEW();
        if (Strings.isNotBlank(key)) {
            key = "%" + key + "%";
            cnd.and(Cnd.exps("u.nickName", "like", key)
                    .or("u.phone", "like", key));
        }
        joinSql.setCondition(cnd);
        sql.appendSourceSql(joinSql.toString());
        sql.appendSourceSql("order by a.balance ");
        countSql.appendSourceSql(joinSql.toString());
        return Result.success().addData(userService.listPage(UserAccountVo.class, pageNumber, pageSize, sql.toString(), countSql.toString()));
    }

    @At()
    @Ok("json:full")
    public Object goDie() {
        ScanParams scanParams = new ScanParams();
        scanParams.match("user:token:*");
        scanParams.count(Integer.MAX_VALUE);
        redisService.del(String.join(",", redisService.scan("0", scanParams).getResult()).split(","));
        return Result.success();
    }

    @At()
    @Ok("json:full")
    public Object getUsers(@Param("key") String key, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize) {
        return Result.success().addData(userService.listPage(pageNumber, pageSize,
                Cnd.where(Cnd.exps("nickName", "like", "%" + key + "%")
                        .or("userName", "like", "%" + key + "%")
                        .or("phone", "like", "%" + key + "%")
                        .or("id", "=", key))
                        .and("delFlag", "=", 0)));
    }

    /**
     * 一键开始游戏大厅
     *
     * @return
     */
    @At()
    @Ok("json:full")
    public Object openAllPlayable() {
        userService.update(Chain.make("playable", 1), Cnd.NEW());
        return Result.success();
    }

    /**
     * 一键关闭游戏大厅
     *
     * @return
     */
    @At()
    @Ok("json:full")
    public Object closeAllPlayable() {
        userService.update(Chain.make("playable", 0), Cnd.NEW());
        return Result.success();
    }

    /*
     * 删除用户（功能关闭）
     * @param id String
     * @return Object
     */
//    @At("/delete/?")
//    @Ok("json")
//    @RequiresPermissions("user.manager.delete")
//    public Object delete(String id) {
//        try {
//            userService.deleteById(id);
//            return Result.success();
//        } catch (Exception e) {
//            return Result.error();
//        }
//
//    }
}
